#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>



using namespace std;

//  only for ipv4 at the moment
//
class	cidr {
	int	bits_;
	uint32_t mask_;
	struct in_addr inad_;
	struct in_addr gwaddr_;
public:
	cidr(const char *net, char *gateway = 0) {
		if (gateway) {
			if (!inet_aton(gateway, &gwaddr_))
				cerr << "cidr::cidr Something wrong with gateway spec '" << gateway << "'" << endl;
		} else {
			memset(&gwaddr_, 0, sizeof (struct in_addr));
		}
		if (!net) {
			bits_ = 0;
			memset(&inad_, 0, sizeof (struct in_addr));
			return;
		}
		bits_ = 32;
		char *mp = strchr(net, '/');

		if (mp) {
			bits_ = strtoul(mp + 1, 0, 0);
			if (bits_ < 0 || bits_ > 32) 
				cerr << "cidr::cidr Something wrong with '" << mp << "'" << endl;
			*mp = '\0';
		}
		mask_ = 0;
		for (int ii = 0; ii < 32 - bits_; ii++, mask_ <<= 1, mask_ |= 1)
			;
		if (!inet_aton(net, &inad_))
			cerr << "cidr::cidr Something wrong with '" << net << "'" << endl;
	}
	bool isLocal(const struct in_addr &in) {
		if (ntohl(in.s_addr) == ntohl(gwaddr_.s_addr))
			return false;
		uint32_t ip = ntohl(in.s_addr) & ~mask_;
		return ip == (ntohl(inad_.s_addr) & ~mask_);
	}
	friend ostream& operator<<(ostream &os, const cidr cdr) {
		char *aip = inet_ntoa(cdr.inad_);
		os << "ip as int " << ntohl(cdr.inad_.s_addr) << " ";
      os << "ip " << aip << " bits " << cdr.bits_ << " mask " << cdr.mask_ << endl;
      return os;
   }
};

